﻿using System.Buffers;
using System.Runtime.CompilerServices;
using static System.Runtime.CompilerServices.MethodImplOptions;

namespace Secs4Net;

partial class Item
{
    public static ListItem L(int capacity) => L("", capacity);
    public static ListItem L(string name, int capacity) => new ListItem(name, capacity);
    public static Item L(IEnumerable<Item> items) => L("", items);
    public static Item L(string name, IEnumerable<Item> items) => L(name, items.ToArray());
    public static Item L(params Item[] items) => L("", items);
    public static Item L(string name, params Item[] items) => items.Length > 0 ? new ListItem(name, items) : new ListItem(name, []);

    public static Item A(string? value) => A("", value);
    public static Item A(string name, string? value) => string.IsNullOrEmpty(value) ? new StringItem(name, SecsFormat.ASCII, string.Empty) : new StringItem(name, SecsFormat.ASCII, value);
    public static Item J(string? value) => J("", value);
    public static Item J(string name, string? value) => string.IsNullOrEmpty(value) ? new StringItem(name, SecsFormat.JIS8, string.Empty) : new StringItem(name, SecsFormat.JIS8, value);

    [MethodImpl(AggressiveInlining)] public static Item B(params byte[] value) => B("", value);
    [MethodImpl(AggressiveInlining)] public static Item B(string name, params byte[] value) => B(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item B(IEnumerable<byte> value) => B("", value);
    [MethodImpl(AggressiveInlining)] public static Item B(string name, IEnumerable<byte> value) => B(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item B(string name, Memory<byte> value) => new MemoryItem<byte>(name, SecsFormat.Binary, value);
    [MethodImpl(AggressiveInlining)] public static Item B(string name, IMemoryOwner<byte> valueOwner) => new MemoryOwnerItem<byte>(name, SecsFormat.Binary, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item U1(params byte[] value) => U1("", value);
    [MethodImpl(AggressiveInlining)] public static Item U1(string name, params byte[] value) => U1(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item U1(IEnumerable<byte> value) => U1("", value);
    [MethodImpl(AggressiveInlining)] public static Item U1(string name, IEnumerable<byte> value) => U1(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item U1(string name, Memory<byte> value) => new MemoryItem<byte>(name, SecsFormat.U1, value);
    [MethodImpl(AggressiveInlining)] public static Item U1(string name, IMemoryOwner<byte> valueOwner) => new MemoryOwnerItem<byte>(name, SecsFormat.U1, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item U2(params ushort[] value) => U2("", value);
    [MethodImpl(AggressiveInlining)] public static Item U2(string name, params ushort[] value) => U2(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item U2(IEnumerable<ushort> value) => U2("", value);
    [MethodImpl(AggressiveInlining)] public static Item U2(string name, IEnumerable<ushort> value) => U2(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item U2(string name, Memory<ushort> value) => new MemoryItem<ushort>(name, SecsFormat.U2, value);
    [MethodImpl(AggressiveInlining)] public static Item U2(string name, IMemoryOwner<ushort> valueOwner) => new MemoryOwnerItem<ushort>(name, SecsFormat.U2, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item U4(params uint[] value) => U4("", value);
    [MethodImpl(AggressiveInlining)] public static Item U4(string name, params uint[] value) => U4(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item U4(IEnumerable<uint> value) => U4("", value);
    [MethodImpl(AggressiveInlining)] public static Item U4(string name, IEnumerable<uint> value) => U4(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item U4(string name, Memory<uint> value) => new MemoryItem<uint>(name, SecsFormat.U4, value);
    [MethodImpl(AggressiveInlining)] public static Item U4(string name, IMemoryOwner<uint> valueOwner) => new MemoryOwnerItem<uint>(name, SecsFormat.U4, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item U8(params ulong[] value) => U8("", value);
    [MethodImpl(AggressiveInlining)] public static Item U8(string name, params ulong[] value) => U8(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item U8(IEnumerable<ulong> value) => U8("", value);
    [MethodImpl(AggressiveInlining)] public static Item U8(string name, IEnumerable<ulong> value) => U8(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item U8(string name, Memory<ulong> value) => new MemoryItem<ulong>(name, SecsFormat.U8, value);
    [MethodImpl(AggressiveInlining)] public static Item U8(string name, IMemoryOwner<ulong> valueOwner) => new MemoryOwnerItem<ulong>(name, SecsFormat.U8, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item I1(params sbyte[] value) => I1("", value);
    [MethodImpl(AggressiveInlining)] public static Item I1(string name, params sbyte[] value) => I1(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item I1(IEnumerable<sbyte> value) => I1("", value);
    [MethodImpl(AggressiveInlining)] public static Item I1(string name, IEnumerable<sbyte> value) => I1(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item I1(string name, Memory<sbyte> value) => new MemoryItem<sbyte>(name, SecsFormat.I1, value);
    [MethodImpl(AggressiveInlining)] public static Item I1(string name, IMemoryOwner<sbyte> valueOwner) => new MemoryOwnerItem<sbyte>(name, SecsFormat.I1, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item I2(params short[] value) => I2("", value);
    [MethodImpl(AggressiveInlining)] public static Item I2(string name, params short[] value) => I2(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item I2(IEnumerable<short> value) => I2("", value);
    [MethodImpl(AggressiveInlining)] public static Item I2(string name, IEnumerable<short> value) => I2(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item I2(string name, Memory<short> value) => new MemoryItem<short>(name, SecsFormat.I2, value);
    [MethodImpl(AggressiveInlining)] public static Item I2(string name, IMemoryOwner<short> valueOwner) => new MemoryOwnerItem<short>(name, SecsFormat.I2, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item I4(params int[] value) => I4("", value);
    [MethodImpl(AggressiveInlining)] public static Item I4(string name, params int[] value) => I4(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item I4(IEnumerable<int> value) => I4("", value);
    [MethodImpl(AggressiveInlining)] public static Item I4(string name, IEnumerable<int> value) => I4(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item I4(string name, Memory<int> value) => new MemoryItem<int>(name, SecsFormat.I4, value);
    [MethodImpl(AggressiveInlining)] public static Item I4(string name, IMemoryOwner<int> valueOwner) => new MemoryOwnerItem<int>(name, SecsFormat.I4, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item I8(params long[] value) => I8("", value);
    [MethodImpl(AggressiveInlining)] public static Item I8(string name, params long[] value) => I8(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item I8(IEnumerable<long> value) => I8("", value);
    [MethodImpl(AggressiveInlining)] public static Item I8(string name, IEnumerable<long> value) => I8(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item I8(string name, Memory<long> value) => new MemoryItem<long>(name, SecsFormat.I8, value);
    [MethodImpl(AggressiveInlining)] public static Item I8(string name, IMemoryOwner<long> valueOwner) => new MemoryOwnerItem<long>(name, SecsFormat.I8, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item F4(params float[] value) => F4("", value);
    [MethodImpl(AggressiveInlining)] public static Item F4(string name, params float[] value) => F4(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item F4(IEnumerable<float> value) => F4("", value);
    [MethodImpl(AggressiveInlining)] public static Item F4(string name, IEnumerable<float> value) => F4(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item F4(string name, Memory<float> value) => new MemoryItem<float>(name, SecsFormat.F4, value);
    [MethodImpl(AggressiveInlining)] public static Item F4(string name, IMemoryOwner<float> valueOwner) => new MemoryOwnerItem<float>(name, SecsFormat.F4, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item F8(params double[] value) => F8("", value);
    [MethodImpl(AggressiveInlining)] public static Item F8(string name, params double[] value) => F8(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item F8(IEnumerable<double> value) => F8("", value);
    [MethodImpl(AggressiveInlining)] public static Item F8(string name, IEnumerable<double> value) => F8(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item F8(string name, Memory<double> value) => new MemoryItem<double>(name, SecsFormat.F8, value);
    [MethodImpl(AggressiveInlining)] public static Item F8(string name, IMemoryOwner<double> valueOwner) => new MemoryOwnerItem<double>(name, SecsFormat.F8, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item Boolean(params bool[] value) => Boolean("", value);
    [MethodImpl(AggressiveInlining)] public static Item Boolean(string name, params bool[] value) => Boolean(name, value.AsMemory());
    [MethodImpl(AggressiveInlining)] public static Item Boolean(IEnumerable<bool> value) => Boolean("", value);
    [MethodImpl(AggressiveInlining)] public static Item Boolean(string name, IEnumerable<bool> value) => Boolean(name, value.ToArray());
    [MethodImpl(AggressiveInlining)] public static Item Boolean(string name, Memory<bool> value) => new MemoryItem<bool>(name, SecsFormat.Boolean, value);
    [MethodImpl(AggressiveInlining)] public static Item Boolean(string name, IMemoryOwner<bool> valueOwner) => new MemoryOwnerItem<bool>(name, SecsFormat.Boolean, valueOwner);

    [MethodImpl(AggressiveInlining)] public static Item L() => EmptyL;
    [MethodImpl(AggressiveInlining)] public static Item A() => EmptyA;
    [MethodImpl(AggressiveInlining)] public static Item J() => EmptyJ;
    [MethodImpl(AggressiveInlining)] public static Item B() => EmptyBinary;
    [MethodImpl(AggressiveInlining)] public static Item U1() => EmptyU1;
    [MethodImpl(AggressiveInlining)] public static Item U2() => EmptyU2;
    [MethodImpl(AggressiveInlining)] public static Item U4() => EmptyU4;
    [MethodImpl(AggressiveInlining)] public static Item U8() => EmptyU8;
    [MethodImpl(AggressiveInlining)] public static Item I1() => EmptyI1;
    [MethodImpl(AggressiveInlining)] public static Item I2() => EmptyI2;
    [MethodImpl(AggressiveInlining)] public static Item I4() => EmptyI4;
    [MethodImpl(AggressiveInlining)] public static Item I8() => EmptyI8;
    [MethodImpl(AggressiveInlining)] public static Item F4() => EmptyF4;
    [MethodImpl(AggressiveInlining)] public static Item F8() => EmptyF8;
    [MethodImpl(AggressiveInlining)] public static Item Boolean() => EmptyBoolean;

    private static readonly Item EmptyL = new ListItem("", []);
    private static readonly Item EmptyA = new StringItem("", SecsFormat.ASCII, string.Empty);
    private static readonly Item EmptyJ = new StringItem("", SecsFormat.JIS8, string.Empty);
    private static readonly Item EmptyBoolean = Boolean("", Memory<bool>.Empty);
    private static readonly Item EmptyBinary = B("", Memory<byte>.Empty);
    private static readonly Item EmptyU1 = U1("", Memory<byte>.Empty);
    private static readonly Item EmptyU2 = U2("", Memory<ushort>.Empty);
    private static readonly Item EmptyU4 = U4("", Memory<uint>.Empty);
    private static readonly Item EmptyU8 = U8("", Memory<ulong>.Empty);
    private static readonly Item EmptyI1 = I1("", Memory<sbyte>.Empty);
    private static readonly Item EmptyI2 = I2("", Memory<short>.Empty);
    private static readonly Item EmptyI4 = I4("", Memory<int>.Empty);
    private static readonly Item EmptyI8 = I8("", Memory<long>.Empty);
    private static readonly Item EmptyF4 = F4("", Memory<float>.Empty);
    private static readonly Item EmptyF8 = F8("", Memory<double>.Empty);
}
